home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / U-Z / VideoToolBox Folder / VideoToolboxSources / RectToAddress.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-14  |  4.7 KB  |  111 lines  |  [TEXT/KAHL]

  1. /* RectToAddress
  2. Finds the memory address of a pixel in a PixMap or BitMap. Completely general:
  3. multiple screens, on or off-screen, BitMaps, PixMaps, and any pixel size.
  4. Doesn't require color quickdraw. The optional parameters return the row length
  5. of the pixmap or bitmap, the pixel size, and the offset in bits into the byte
  6. (for pixels that are smaller than a byte).
  7.  
  8. The returned address corresponds to the upper-left pixel in *myRectPtr in *myPixMapPtr. 
  9. If it's an off-screen Pix/BitMap clips *myRectPtr to the PixMap bounds;
  10. if it's on-screen clips *myRectPtr to that screen device. Returns NULL if
  11. *myRectPtr is empty after clipping. 
  12.  
  13. Note that many video cards have video memory that is only accessible when your computer
  14. is in 32-bit addressing mode, so you should only access the address returned by
  15. RectToAddress inside a block of code that operates in 32-bit addressing mode. 
  16. Use SwapMMUMode(), which is documented in Apple's Inside Macintosh.
  17.  
  18. Copyright ©1989-1993 Denis G. Pelli.
  19.  
  20. HISTORY:
  21. 4/89    dgp    v. 1.0 extracted it from CopyBitsQuickly.
  22. 2/91    dgp    v. 1.1 no longer requires color quickdraw.
  23. 4/5/91    dgp    v. 1.2 fixed overflow bug reported by Brady Duga.
  24. 8/24/91    dgp    Made compatible with THINK C 5.0.
  25. 4/27/92    dgp    Though I haven't experienced any problems I took the advice of Apple's
  26.             Inside Mac VI and now get the pixmap base address by means of the new
  27.             GetPixBaseAddr() if that trap is available.
  28. 7/13/92    dgp    enhanced the documentation above. Removed support for THINK C version 4.
  29. 1/11/93    dgp only call GetPixBaseAddr() for PixMap, not for BitMap.
  30. 2/7/93    dgp    return NULL if supplied pix/bitmap pointer is NULL.
  31. 3/14/93    dgp    Use GetPixBaseAddr() only if the working version is present, i.e.
  32.             not the first version of 32-bit QuickDraw.
  33. */
  34. #include "VideoToolbox.h"
  35.     
  36. unsigned char *RectToAddress(PixMap *myPixMapPtr,Rect *myRectPtr,short *myRowBytesPtr, 
  37.     short *myPixelSizePtr,short *bitsOffsetPtr)
  38. /*
  39. *myPixMapPtr is the PixMap or BitMap that you're working in.
  40. *myRectPtr is the Rect you're interested in, in local coordinates. 
  41.     Will be clipped by device bounds.
  42. *myRowBytesPtr optionally returns rowBytes.
  43. *myPixelSizePtr optionally returns pixelSize.
  44. *bitsOffsetPtr optionally returns positive offset in bits from returned
  45.     byte address to the location specified by upper left corner of myRectPtr
  46. */
  47. {
  48.     GDHandle device,mainDevice;
  49.     Rect rect,smallRect;
  50.     register Ptr address;
  51.     int notEmpty;
  52.     int x0,y0;
  53.     long qD;
  54.     
  55.     if(myPixMapPtr==NULL)return NULL;
  56.     Gestalt(gestaltQuickdrawVersion,&qD);
  57.     x0=myPixMapPtr->bounds.left;
  58.     y0=myPixMapPtr->bounds.top;
  59.     if(qD>=gestalt8BitQD)mainDevice=GetMainDevice();
  60.     else mainDevice=NULL;
  61.     // GetPixBaseAddr() did not work in the first version of 32-bit QuickDraw
  62.     if(qD>=gestalt32BitQD12 && myPixMapPtr->rowBytes & 0x8000)
  63.         address=GetPixBaseAddr(&myPixMapPtr);
  64.     else address=myPixMapPtr->baseAddr;
  65.     if(address==NULL)return NULL;
  66.     if(mainDevice != NULL && address == (*(*mainDevice)->gdPMap)->baseAddr){
  67.         /* When there are multiple screens, all windows refer to main device PixMap */
  68.         /* so we have to figure out which is the actual device. */
  69.         rect = *myRectPtr;
  70.         OffsetRect(&rect,-x0,-y0);            /* convert to global coordinates */
  71.         /* Find device that displays the upper left pixel */
  72.         smallRect = rect;
  73.         smallRect.bottom=smallRect.top+1;
  74.         smallRect.right=smallRect.left+1;
  75.         device = GetMaxDevice(&smallRect);
  76.         if(device==NULL)return NULL;
  77.         myPixMapPtr = *(*device)->gdPMap;    /* Use the DEVICE'S PixMap */
  78.         // GetPixBaseAddr() did not work in the first version of 32-bit QuickDraw
  79.         if(qD>=gestalt32BitQD12)address=GetPixBaseAddr(&myPixMapPtr);
  80.         else address=myPixMapPtr->baseAddr;
  81.         notEmpty=SectRect(&rect,&myPixMapPtr->bounds,&rect);
  82.         if(!notEmpty) return NULL;    
  83.         *myRectPtr=rect;
  84.         OffsetRect(myRectPtr,x0,y0);        /* convert back to local coordinates */
  85.         /* convert to device coordinates */
  86.         OffsetRect(&rect,-(*device)->gdRect.left,-(*device)->gdRect.top);
  87.     }
  88.     else {
  89.         /* Just clip and convert to global coordinates */
  90.         rect = *myRectPtr;
  91.         notEmpty=SectRect(&rect,&myPixMapPtr->bounds,&rect);
  92.         if(!notEmpty) return NULL;    
  93.         OffsetRect(&rect,-x0,-y0);            /* convert to global coordinates */
  94.     }
  95.     address += rect.top*(long)(myPixMapPtr->rowBytes & 0x1fff);
  96.     if(myPixMapPtr->rowBytes & 0x8000){                    /* Pixmap or Bitmap? */
  97.         /* Pixmap */
  98.         address += (rect.left*(long)myPixMapPtr->pixelSize)/8;
  99.         if(bitsOffsetPtr != NULL) *bitsOffsetPtr=(rect.left*(long)myPixMapPtr->pixelSize)%8;
  100.         if(myPixelSizePtr != NULL) *myPixelSizePtr=myPixMapPtr->pixelSize;
  101.     }
  102.     else{
  103.         /* Bitmap */
  104.         address += rect.left/8;        
  105.         if(bitsOffsetPtr != NULL) *bitsOffsetPtr=rect.left%8;
  106.         if(myPixelSizePtr != NULL) *myPixelSizePtr=1;
  107.     }
  108.     if(myRowBytesPtr != NULL) (*myRowBytesPtr)=myPixMapPtr->rowBytes & 0x1fff;
  109.     return (unsigned char *) address;
  110. }
  111.